server-side-props.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
  2. import {
  3. SupportedAction,
  4. type SupportedActionType,
  5. } from '~/interfaces/activity';
  6. import type { IShareLinkHasId } from '~/interfaces/share-link';
  7. import {
  8. getServerSideCommonInitialProps,
  9. getServerSideI18nProps,
  10. } from '../../common-props';
  11. import {
  12. getServerSideGeneralPageProps,
  13. getServerSideRendererConfigProps,
  14. isValidGeneralPageInitialProps,
  15. } from '../../general-page';
  16. import { addActivity } from '../../utils/activity';
  17. import { mergeGetServerSidePropsResults } from '../../utils/server-side-props';
  18. import { getPageDataForInitial } from './page-data-props';
  19. import type { Stage2InitialProps } from './types';
  20. const basisProps = {
  21. props: {
  22. isNotCreatable: true,
  23. isForbidden: false,
  24. isIdenticalPathPage: false,
  25. },
  26. };
  27. function getActivityAction(props: {
  28. isExpired: boolean | undefined;
  29. shareLink: IShareLinkHasId | undefined;
  30. }): SupportedActionType {
  31. if (props.isExpired) {
  32. return SupportedAction.ACTION_SHARE_LINK_EXPIRED_PAGE_VIEW;
  33. }
  34. if (props.shareLink == null) {
  35. return SupportedAction.ACTION_SHARE_LINK_NOT_FOUND;
  36. }
  37. return SupportedAction.ACTION_SHARE_LINK_PAGE_VIEW;
  38. }
  39. export async function getServerSidePropsForInitial(
  40. context: GetServerSidePropsContext,
  41. ): Promise<GetServerSidePropsResult<Stage2InitialProps>> {
  42. const [
  43. commonInitialResult,
  44. generalPageResult,
  45. rendererConfigResult,
  46. i18nPropsResult,
  47. pageDataResult,
  48. ] = await Promise.all([
  49. getServerSideCommonInitialProps(context),
  50. getServerSideGeneralPageProps(context),
  51. getServerSideRendererConfigProps(context),
  52. getServerSideI18nProps(context, ['translation']),
  53. getPageDataForInitial(context),
  54. ]);
  55. // Merge all results in a type-safe manner (using sequential merging)
  56. const mergedResult = mergeGetServerSidePropsResults(
  57. commonInitialResult,
  58. mergeGetServerSidePropsResults(
  59. generalPageResult,
  60. mergeGetServerSidePropsResults(
  61. rendererConfigResult,
  62. mergeGetServerSidePropsResults(
  63. i18nPropsResult,
  64. mergeGetServerSidePropsResults(pageDataResult, basisProps),
  65. ),
  66. ),
  67. ),
  68. );
  69. // Check for early return (redirect/notFound)
  70. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  71. return mergedResult;
  72. }
  73. const mergedProps = await mergedResult.props;
  74. // Type-safe props validation AFTER skipSSR is properly set
  75. if (!isValidGeneralPageInitialProps(mergedProps)) {
  76. throw new Error('Invalid merged props structure');
  77. }
  78. // Persist activity
  79. addActivity(context, getActivityAction(mergedProps));
  80. return mergedResult;
  81. }